<html>
<head><meta charset="utf-8"><title>passing Vec&lt;Box&lt;T&gt;&gt; references to functions · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html">passing Vec&lt;Box&lt;T&gt;&gt; references to functions</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="248438807"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248438807" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BOB <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248438807">(Aug 05 2021 at 05:02)</a>:</h4>
<p>What's the convention around Vec&lt;Box&lt;T&gt;&gt; and passing a reference to it to functions? If you do it naively, you get a <code>&amp;[Box&lt;T&gt;]</code>. Is that considered good style? Intuitively it seems like one would really want a <code>&amp;[&amp;T]</code>, but that's not easy to get.</p>



<a name="248438837"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248438837" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248438837">(Aug 05 2021 at 05:03)</a>:</h4>
<p>why do you have Vec&lt;Box&lt;T&gt;&gt; anyway? that's two indirections, which is bad for performance</p>



<a name="248439051"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248439051" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> BOB <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248439051">(Aug 05 2021 at 05:06)</a>:</h4>
<p>it's necessary for interop with some other things - we get it from another API and making it a Vec&lt;T&gt; would require copying the whole vector</p>



<a name="248439490"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248439490" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248439490">(Aug 05 2021 at 05:17)</a>:</h4>
<p>hmm, ok. I don't think you can do &amp;[&amp;T] without copying, because Box and &amp; have different layouts - <code>Box</code> stores an allocator and <code>&amp;</code> does not: <a href="https://doc.rust-lang.org/src/alloc/boxed.rs.html#176">https://doc.rust-lang.org/src/alloc/boxed.rs.html#176</a></p>



<a name="248439854"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248439854" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248439854">(Aug 05 2021 at 05:24)</a>:</h4>
<p>you get <code>&amp;[Box&lt;T&gt;]</code> but that box will itself turn into <code>&amp;T </code> when necessary, so it's not a big deal if you're using them one at a time.</p>



<a name="248440741"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248440741" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248440741">(Aug 05 2021 at 05:45)</a>:</h4>
<p><span class="user-mention silent" data-user-id="232545">Joshua Nelson</span> <a href="#narrow/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions/near/248439490">said</a>:</p>
<blockquote>
<p>hmm, ok. I don't think you can do &amp;[&amp;T] without copying, because Box and &amp; have different layouts - <code>Box</code> stores an allocator and <code>&amp;</code> does not: <a href="https://doc.rust-lang.org/src/alloc/boxed.rs.html#176">https://doc.rust-lang.org/src/alloc/boxed.rs.html#176</a></p>
</blockquote>
<p><code>Box&lt;T, Global&gt;</code> is guaranteed to just be the same layout as a pointer. This has been around for a long time, and FFI uses it often</p>



<a name="248441052"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248441052" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248441052">(Aug 05 2021 at 05:53)</a>:</h4>
<p><a href="https://doc.rust-lang.org/std/boxed/index.html#memory-layout">https://doc.rust-lang.org/std/boxed/index.html#memory-layout</a></p>
<p>So, I am fairly certain that <code>&amp;[Box&lt;T, Global&gt;]</code> =&gt; <code>&amp;[&amp;T]</code> is fine without copying.</p>



<a name="248441115"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248441115" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248441115">(Aug 05 2021 at 05:54)</a>:</h4>
<p>Correct. But there's just not a safe way to do it in one step like that, at least not one I know of.</p>



<a name="248441130"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248441130" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248441130">(Aug 05 2021 at 05:55)</a>:</h4>
<p>yeah, it needs unsafe.</p>



<a name="248441997"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248441997" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Kestrer <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248441997">(Aug 05 2021 at 06:12)</a>:</h4>
<p>I will often use a <code>&amp;[impl Borrow&lt;T&gt;]</code> so you support lots of types like <code>&amp;[T]</code>, <code>&amp;[Box&lt;T&gt;]</code>, <code>&amp;[&amp;T]</code> etc</p>



<a name="248442038"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248442038" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248442038">(Aug 05 2021 at 06:13)</a>:</h4>
<p><span class="user-mention silent" data-user-id="209168">Thom Chiovoloni</span> <a href="#narrow/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions/near/248440741">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="232545">Joshua Nelson</span> <a href="#narrow/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions/near/248439490">said</a>:</p>
<blockquote>
<p>hmm, ok. I don't think you can do &amp;[&amp;T] without copying, because Box and &amp; have different layouts - <code>Box</code> stores an allocator and <code>&amp;</code> does not: <a href="https://doc.rust-lang.org/src/alloc/boxed.rs.html#176">https://doc.rust-lang.org/src/alloc/boxed.rs.html#176</a></p>
</blockquote>
<p><code>Box&lt;T, Global&gt;</code> is guaranteed to just be the same layout as a pointer. This has been around for a long time, and FFI uses it often</p>
</blockquote>
<p>uhhh that's super concerning, because the docs say "layout compatible", but there is no <code>repr(transparent)</code> there</p>



<a name="248442060"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248442060" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248442060">(Aug 05 2021 at 06:14)</a>:</h4>
<p>so the compiler does _not_ guarentee it has the same layout as <code>Unique&lt;T&gt;</code></p>



<a name="248442215"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248442215" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248442215">(Aug 05 2021 at 06:17)</a>:</h4>
<p>the only way for that to be guarenteed is for the compiler to special-case the lang_item attribute, but that's some very non-local reasoning and I wouldn't be surprised if it regressed unless it's tested somehow</p>



<a name="248442361"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248442361" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Kestrer <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248442361">(Aug 05 2021 at 06:20)</a>:</h4>
<p>The standard library is special, so it is allowed to rely on the current <code>repr(Rust)</code> layout</p>



<a name="248442369"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248442369" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Kestrer <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248442369">(Aug 05 2021 at 06:20)</a>:</h4>
<p>It relies on implementation details in many places actually</p>



<a name="248442386"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248442386" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248442386">(Aug 05 2021 at 06:20)</a>:</h4>
<p>also, if it were to regress then like, wildly huge amounts of rust would break probably in the very next nightly release</p>



<a name="248446158"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248446158" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248446158">(Aug 05 2021 at 07:28)</a>:</h4>
<p>From the <a href="https://doc.rust-lang.org/std/boxed/index.html#memory-layout">docs</a>:</p>
<blockquote>
<p>For non-zero-sized values, a Box will use the Global allocator for its allocation. It is valid to convert both ways between a Box and a raw pointer allocated with the Global allocator, given that the Layout used with the allocator is correct for the type. More precisely, a value: <em>mut T that has been allocated with the Global allocator with Layout::for_value(&amp;</em>value) may be converted into a box using Box::&lt;T&gt;::from_raw(value). Conversely, the memory backing a value: <em>mut T obtained from Box::&lt;T&gt;::into_raw may be deallocated using the Global allocator with Layout::for_value(&amp;</em>value).<br>
(...)<br>
Even though Box&lt;T&gt; has the same representation and C ABI as a C pointer, this does not mean that you can convert an arbitrary T* into a Box&lt;T&gt; and expect things to work. Box&lt;T&gt; values will always be fully aligned, non-null pointers. Moreover, the destructor for Box&lt;T&gt; will attempt to free the value with the global allocator. In general, the best practice is to only use Box&lt;T&gt; for pointers that originated from the global allocator.</p>
</blockquote>
<p>I don't think that means it's layout compatible in the sense of <code>#[repr(transparent)]</code>. Just that we can convert between raw pointers and a Box using the <code>Box::&lt;T&gt;::from_raw(value)</code> and <code>Box::&lt;T&gt;::into_raw</code> methods. Note that the memory model for <code>Box&lt;T&gt;</code> is not set in stone yet, particularly in light of its aliasing rules: <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/258">https://github.com/rust-lang/unsafe-code-guidelines/issues/258</a> (I have no idea about which direction it will end up going in, but as long as it's being discussed, I don't think we can consider it as a stable guarantee :-) ) Even if we assume that <code>Box&lt;T&gt;</code> and <code>&amp;T</code> are layout compatible, converting between these using <code>unsafe</code> might have other unexpected implications (e.g. pointer provenance).</p>



<a name="248534431"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248534431" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Kestrer <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248534431">(Aug 05 2021 at 20:50)</a>:</h4>
<p>The aliasing rules of Box are separate from the layout of Box. Its layout is definitely specified to be equivalent to a pointer. The relavant quote is:</p>
<blockquote>
<p>So long as T: Sized, a Box&lt;T&gt; is guaranteed to be represented as a single pointer and is also ABI-compatible with C pointers (i.e. the C type T*).</p>
</blockquote>
<p>But yes, I would still be cautious about <code>&amp;[Box&lt;T&gt;] -&gt; &amp;[&amp;T]</code> because although it is guaranteed to work at an ABI level, aliasing rules are in flux and confusing. Especially when there are fully safe alternatives there's no point in discussing this :)</p>



<a name="248559774"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248559774" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248559774">(Aug 06 2021 at 02:19)</a>:</h4>
<p>what is your fully safe alternative?</p>



<a name="248560655"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248560655" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248560655">(Aug 06 2021 at 02:37)</a>:</h4>
<p><code>&amp;[Box&lt;T&gt;]</code> :P</p>



<a name="248575218"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248575218" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Kestrer <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248575218">(Aug 06 2021 at 06:14)</a>:</h4>
<p>That or <code>&amp;[impl Borrow&lt;T&gt;]</code></p>



<a name="248589183"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248589183" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248589183">(Aug 06 2021 at 09:33)</a>:</h4>
<p>I fail to see how <code>&amp;Box</code> could carry aliasing information about that <code>Box</code>: if the <code>Box</code>, itself, is aliased / shared, then the <code>Box</code>'s pointee may very well be aliased as well, so the compiler can't assume any extra property between <code>&amp;Box&lt;T&gt;</code> and <code>&amp;&amp;T</code>.</p>
<ul>
<li>(this reminds me of the very interesting <code>&amp;'outer &amp;'inner mut T</code> reference type which is not a stronger but a weaker reference type than <code>&amp;'outer &amp;'inner T</code>, since you can't get a <code>&amp;'inner T</code> out of it).</li>
</ul>



<a name="248619400"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248619400" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248619400">(Aug 06 2021 at 14:40)</a>:</h4>
<p>Uhm, if a function <em>you didn't write</em> takes <code>&amp;[&amp;T]</code> then nothing that any of yall said is a safe alternative way to call that function :P</p>



<a name="248655625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248655625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Kestrer <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248655625">(Aug 06 2021 at 19:12)</a>:</h4>
<p>Well that wasn't the question was it <span aria-label="big smile" class="emoji emoji-1f604" role="img" title="big smile">:big_smile:</span></p>



<a name="248661739"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248661739" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248661739">(Aug 06 2021 at 20:05)</a>:</h4>
<p>Here is a safe way to convert to <code>&amp;[&amp;T]</code>, but at the cost of an extra allocation :P <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=638bce27f83c8781dcbc66cad7a56847">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=638bce27f83c8781dcbc66cad7a56847</a></p>



<a name="248696155"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248696155" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Notification Bot <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248696155">(Aug 07 2021 at 04:48)</a>:</h4>
<p><span class="user-mention silent" data-user-id="431151">dswijj</span> has marked this topic as resolved.</p>



<a name="248696158"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248696158" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Notification Bot <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248696158">(Aug 07 2021 at 04:48)</a>:</h4>
<p><span class="user-mention silent" data-user-id="431151">dswijj</span> has marked this topic as unresolved.</p>



<a name="248706575"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248706575" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248706575">(Aug 07 2021 at 09:16)</a>:</h4>
<p><span class="user-mention silent" data-user-id="232018">Daniel Henry-Mantilla</span> <a href="#narrow/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions/near/248589183">said</a>:</p>
<blockquote>
<p>I fail to see how <code>&amp;Box</code> could carry aliasing information about that <code>Box</code>: if the <code>Box</code>, itself, is aliased / shared, then the <code>Box</code>'s pointee may very well be aliased as well, so the compiler can't assume any extra property between <code>&amp;Box&lt;T&gt;</code> and <code>&amp;&amp;T</code>.</p>
<ul>
<li>(this reminds me of the very interesting <code>&amp;'outer &amp;'inner mut T</code> reference type which is not a stronger but a weaker reference type than <code>&amp;'outer &amp;'inner T</code>, since you can't get a <code>&amp;'inner T</code> out of it).</li>
</ul>
</blockquote>
<p>Here is a fun mind-experiment: <a href="https://play.rust-lang.org/?version=stable&amp;mode=release&amp;edition=2018&amp;gist=1f92fb01ec19841a2d327bd52d501dc7">https://play.rust-lang.org/?version=stable&amp;mode=release&amp;edition=2018&amp;gist=1f92fb01ec19841a2d327bd52d501dc7</a></p>
<p>This is not undefined behavior under the current  Stacked Borrows implementation in Miri (try Tools &gt; Miri on the playground). Of course, this dirty code example relies on the assumption that <code>Box&lt;T&gt;</code> has the same size and layout as <code>*mut T</code> for <code>#[repr(Rust)]</code>, which is only guaranteed for the C ABI which gets invoked across FFI boundaries if I understand the <a href="https://doc.rust-lang.org/std/boxed/index.html#memory-layout">documentation</a> over at <code>Box&lt;T&gt;</code> correctly. </p>
<p>But, what exactly does <code>#[repr(Rust)]</code> mean for <code>Box&lt;T&gt;</code>? (From the official reference](<a href="https://doc.rust-lang.org/reference/type-layout.html#the-default-representation">https://doc.rust-lang.org/reference/type-layout.html#the-default-representation</a>):</p>
<blockquote>
<p>Nominal types without a repr attribute have the default representation. Informally, this representation is also called the rust representation.</p>
<p>There are no guarantees of data layout made by this representation.</p>
</blockquote>
<p>This agrees with the reading of the <code>Box&lt;T&gt;</code> documentation. However, unofficially the Rust Unsafe Code Guidelines Reference (disclaimer: these are just "<a href="https://rust-lang.github.io/unsafe-code-guidelines/introduction.html">recommendations</a>" and not part of the official reference - yet), <a href="https://rust-lang.github.io/unsafe-code-guidelines/layout/structs-and-tuples.html">says the following</a> about <code>#[repr(Rust)]</code>:</p>
<blockquote>
<p><strong>Struct types</strong><br>
(...)<br>
In terms of their layout, tuple structs can be understood as equivalent to a named struct with fields named 0..n-1<br>
(...)<br>
<strong>Single-field structs</strong><br>
A struct with only one field has the same layout as that field.</p>
<p><strong>Structs with 1-ZST fields</strong><br>
For the purposes of struct layout 1-ZST fields are ignored.</p>
<p>In particular, if all but one field are 1-ZST, then the struct is equivalent to a single-field struct. In other words, if all but one field is a 1-ZST, then the entire struct has the same layout as that one field.</p>
<p>Similarly, if all fields are 1-ZST, then the struct has the same layout as a struct with no fields, and is itself a 1-ZST.<br>
(...)</p>
</blockquote>
<p>The type definition of <code>Box</code> is:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nb">Box</span><span class="o">&lt;</span><span class="w"></span>
<span class="w">    </span><span class="n">T</span>: <span class="o">?</span><span class="nb">Sized</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">A</span>: <span class="nc">Allocator</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Global</span><span class="p">,</span><span class="w"></span>
<span class="o">&gt;</span><span class="p">(</span><span class="n">Unique</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">A</span><span class="p">);</span><span class="w"></span>
</code></pre></div>
<p>The <code>Global</code> allocator is a 1-ZST (i.e. a zero sized type which is aligned to a 1-byte boundary). So the layout of a <code>Box&lt;T, Global&gt;</code> then is the same as the layout of a <code>Unique&lt;T&gt;</code>, which is the only sized field of the tuple struct <code>Box&lt;T, Global&gt;</code>. The <a href="https://docs.rs/ptr/0.2.3/src/ptr/lib.rs.html#43-51">type definition of <code>Unique</code></a> is:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">Unique</span><span class="o">&lt;</span><span class="n">T</span>: <span class="o">?</span><span class="nb">Sized</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">ptr</span>: <span class="nc">NonNull</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">_marker</span>: <span class="nc">PhantomData</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Here, <code>PhantomData&lt;T&gt;</code> is again a 1-ZST, so <code>Unique&lt;T&gt;</code> has the same layout as <code>NonNull&lt;T&gt;</code> and transitively <code>Box&lt;T, Global&gt;</code> has the same layout as <code>NonNull&lt;T&gt;</code>. The <a href="https://doc.rust-lang.org/src/core/ptr/non_null.rs.html#50-52">type definition of <code>NonNull</code></a> is:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[repr(transparent)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">NonNull</span><span class="o">&lt;</span><span class="n">T</span>: <span class="o">?</span><span class="nb">Sized</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">pointer</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">T</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>And it is <code>#[repr(transparent)]</code> with a raw pointer! Thus, if we follow the reasoning of the Unsafe Code Guidelines Reference, then <code>Box&lt;T, Global&gt;</code> has the same memory layout as a raw pointer. Again disclaimer: this could still change, as the guidelines state in its <a href="https://rust-lang.github.io/unsafe-code-guidelines/introduction.html">introduction</a>. And that is probably the reason why the official Rust reference doesn't claim this is defined behavior, so that the language designers have the freedom to make changes if needed :-)</p>
<p>So what was the purpose of the code example at the beginning of this reply? Well, for science of course! And just to show that in today's compilation, it is possible to convert <code>&amp;[Box&lt;T&gt;]</code> to <code>&amp;[*mut T]</code> and <code>&amp;[&amp;T]</code> under the (unstable) assumptions of the Unsafe Code Guidelines and Stacked Borrows model. But because these guidelines are still unstable, it is also undefined behavior under the official Rust reference, even though it actually compiles and works as expected :)</p>



<a name="248706923"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248706923" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248706923">(Aug 07 2021 at 09:27)</a>:</h4>
<blockquote>
<p>The type definition of Box is:</p>
</blockquote>
<p>Those aren't public, so you wouldn't be allowed to use that information in your reasoning.</p>



<a name="248710929"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248710929" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248710929">(Aug 07 2021 at 11:06)</a>:</h4>
<p>That's a very good point. <code>Box</code>,  <code>PhantomData</code>, <code>NonNull</code>, the <code>Allocator</code> trait and <code>Global</code> are all public (the last 2 only behind a nightly feature gate <code>allocator_api</code>), but <code>Unique</code> is only available to the core/standard library :) Unless your manually import the <code>ptr</code> crate, but the standard library makes no external guarantees about the internal use of <code>Unique</code>, I believe, so that wouldn't make much sense indeed.</p>



<a name="248712784"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248712784" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248712784">(Aug 07 2021 at 11:54)</a>:</h4>
<p>I meant the fields, those aren't public.</p>



<a name="248714953"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248714953" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248714953">(Aug 07 2021 at 12:51)</a>:</h4>
<p><span class="user-mention" data-user-id="400735">@Pointerbender</span> note: the reference isn't actually normative either</p>



<a name="248715026"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248715026" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248715026">(Aug 07 2021 at 12:53)</a>:</h4>
<p>Isn't Box defined to have the same layout as *mut T?</p>



<a name="248718689"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248718689" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248718689">(Aug 07 2021 at 14:23)</a>:</h4>
<p>not for all T</p>



<a name="248719037"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248719037" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248719037">(Aug 07 2021 at 14:31)</a>:</h4>
<p>only for the Global allocator and for sized T</p>



<a name="248719263"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/passing%20Vec%3CBox%3CT%3E%3E%20references%20to%20functions/near/248719263" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/passing.20Vec.3CBox.3CT.3E.3E.20references.20to.20functions.html#248719263">(Aug 07 2021 at 14:36)</a>:</h4>
<p>though i didn't mean that to any specific statement being wrong, just that the reference cannot be taken as any more correct than any other part of Rust.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>